import sys, os
from config import APP_DEBUG, WS_LOG_FILE
from common import now
from traceback import print_exc
from io import StringIO


class Log:

    def __init__(self, logfile=None, *args, **kwargs):
        if APP_DEBUG == '1':
            self.file = sys.stdout
        else:
            if logfile is None:
                #  logfile = '%s/%s.log' % (APP_RUN_DIR, type(self).__name__)
                logfile = WS_LOG_FILE
            self.file = open(logfile, 'a+')

    def __del__(self):
        if self.file is not sys.stdout:
            self.file.close()

    def __log_to_string(self, name, *args):
        sf = StringIO()
        print("%s<%s / %s>" % (name, os.getpid(), now()), *args, end=' ',
              file=sf, flush=True)
        content = sf.getvalue()
        sf.close()
        return content

    def log(self, name, *args, **kwargs):
        content = self.__log_to_string(name, *args)
        print(content, file=self.file, flush=True, **kwargs)
        return content

    def out(self, *args, **kwargs):
        return self.log('STDOUT: ', *args, **kwargs)

    def __stack_to_string(self):
        sf = StringIO()
        print_exc(file=sf)
        content = sf.getvalue()
        sf.close()
        return content

    def err(self, *args, stack=False, **kwargs):
        content = self.log('STDERR: ', *args, **kwargs)
        if stack:
            stack_string = self.__stack_to_string()
            print(stack_string, file=self.file, flush=True)
            content += stack_string
        return content

def log():
    if not hasattr(out, 'obj'):
        log.obj = Log()
    return log.obj

def out(*args, **kwargs):
    return log().out(*args, **kwargs)

def err(*args, **kwargs):
    return log().err(*args, **kwargs)

